package com.homework.ch06;
/*
基础知识：JVM的内存结构：
栈区：局部变量，方法调用 随着方法的调用结束而销毁
堆区：对象实例和数组真实值  自动垃圾回收机制自动回收空间
方法区：分为类元数据区 运行时的常量池 静态区 在、垃圾回收机制回收空间
       类元数据区：存放类名，权限访问修饰符，字段，方法
       运行时的常量池：字面量
       静态区：被static修饰的属性，方法，代码块
本地方法栈：Native方法调用
* 1.static关键字
*   static是什么？static是一个修饰符，表示静态的意思（即与类相关，而非实例对象），
*               可以修饰属性，方法和代码块，这些被static修饰占用单独的内存空间（静态区），被所有对象共享（包括操作）
*   为什么要用到static?
* 2.static的用法？static可以修饰属性，方法和代码块-》静态变量/属性 静态方法 静态代码块
*   2.1 静态变量 被static修饰的变量 属性不依赖任何实例对象就可以使用 所有对象共享的数据
*       语法：权限修饰符 static 数据类型 变量名；
        使用方法：
               类内部使用：直接使用名字  类名.静态变量名(推荐) this.静态变量名
               对象使用:公开的使用对象名.静态变量名 类名.静态变量名（s推荐） 私有的使用get/set方法对静态变量的访问
        特点：
            静态变量被所有对象共享
            静态变量只存储一份，存在方法区中的静态区
            静态属性在类加载的时候就创建了，比创建对象要早，静态属性不赋值就是各个数据类型的默认值，显式初始化就是显式值；
*       内存和执行顺序：首先会进行类加载-》静态属性存储到静态区（基本数据类型都存储在静态区，引用类型的静态变量本身的引用存储在方法区中的静态区，引用指向的对象存储在堆区）
                    静态属性的阿值不写就是默认值，显式显式初始化就是显式值；然后才会进入main方法创建对象之类的操作
*   2.2静态方法 被static修饰的方法 方法不依赖任何实例对象 所有对象共享的方法
*       语法：权限修饰符 static 返回值 静态方法名（参数列表）{方法体}
        使用：
            类内部调用静态方法：直接调用 类名.静态方法调用(推荐) this.静态方法调用
            对象使用静态方法：公开的 对象名.静态方法调用 类名.静态方法调用
        特点：
            所有对象共享
            存在方法区中的静态区
            在类加载的时候就创建了比创建对象要早
            只能访问静态变量，访问静态方法，不能使用this以及成员变量和成员方法                      成员方法：使用成员变量和静态变量也可以是使用成员方法和静态方法，因为静态修饰的属性方法代码块是所有对象共享的
*                                                                                       静态方法：只能访问静态属性和静态方法，因为静态区是在类加载的时候就创建了，比对象创建的早
        内存和执行顺序：首先进行类加载-》静态方法存储到静态区，进入main函数，等到调用的时候就会在栈中创建函数栈帧
*   2.3静态代码块
*       语法：类中方法外static{代码}，static{num=1;}，只能访问静态属性和方法
        特点：类加载的时候就执行一次（后面不在执行），在对象创建之前就执行，一般给静态变量默认初始化，对于显式初始化和静态代码块谁在前限制行谁
*       内存和执行顺序：
*拓展：代码块 分为局部代码块 构造代码块 静态代码块
    局部代码块：
            是什么：在方法体中的{代码}，常见的如for{}，while{}，{}，类中方法内的{}等
            怎么执行：按照顺序从main开始上到下执行，生命周期和作用域在’{‘开始，’}‘结束
            内存：main执行到’{‘对这个代码块创建匿名函数栈帧，开始执行局部代码块中的代码，遇见‘}’就销毁函数栈帧；
    构造代码块：
            是什么：写在类中方法外的{代码}，比如 class Dog{int id {} public void show(){}}
            怎么执行：new的时候首先会初始化属性-》显式初始化/构造代码块-》构造函数，谁在前先执行谁
            内存：new之后先向堆区开辟空间并初始化-》调用构造代码块-》构造函数-》返回地址
* */
//下面的就是没有使用static修饰library是每个对象的
/*public class School {
    private String name;
    private int num;
    private String library;
    public School(String name,int num,String library)
    {
        this.name=name;
        this.num=num;
        this.library=library;
    }
    public void setName(String name)
    {
        this.name=name;
    }
    public void setNum(int num)
    {
        this.num=num;
    }
    public void setLibrary(String library)
    {
        this.library=library;
    }
    public String getName()
    {
        return this.name;
    }
    public int getNum()
    {
        return this.num;
    }
    public String getLibrary()
    {
        return this.library;
    }
}*/
public class School{
    private String name;
    private int num;
    //1.静态属性
    private static String library;//不写就是默认值（各个数据类型的默认值） 显式初始化就是显式值
    public School(){}
    public School(String name,int num)
    {
        this.name=name;
        this.num=num;
    }
    public void setName(String name)
    {
        this.name=name;
    }
    public void setNum(int num)
    {
        this.num=num;
    }
    public String getName()
    {
        return this.name;
    }
    public int getNum()
    {
        return this.num;
    }
    static public String getLibrary()
    {
        return School.library;
    }
    static public void printLibrary()
    {
        getLibrary();
    }
    public String setLibrary(String library)
    {

        return School.library=library;
    }
    public void show()
    {
        System.out.println("直接调用"+getLibrary());
        System.out.println("this调用"+this.getLibrary());
        System.out.println("类名调用"+School.getLibrary());
        System.out.println("name:"+this.name+"num:"+this.num+"library:"+School.library);//library this.library School.library都可以
    }
    {
        name="hihi";
        System.out.println("构造代码块03"+name);
    }
    {
        name="haha";
        System.out.println("构造代码块01"+name);
    }
    {
        name="hehe";
        System.out.println("构造代码块02"+name);
    }


}